# steam_api_client.py
import requests
import logging
from typing import List, Optional, Dict, Any
from models import Game  # 导入之前定义的Game模型

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


class SteamAPIClient:
    """
    负责与Steam Store API (特别是appdetails接口) 交互的客户端。
    """
    BASE_URL = "https://store.steampowered.com/api/"
    DEFAULT_HEADERS = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
    }

    def __init__(self, country_code: str = "CN", language: str = "schinese"):
        """
        初始化SteamAPIClient。
        Args:
            country_code (str): 国家代码，影响价格和可用性 (e.g., 'CN', 'US').
            language (str): 语言代码，影响返回信息的语言 (e.g., 'schinese', 'english').
        """
        self.country_code = country_code
        self.language = language
        self.headers = self.DEFAULT_HEADERS.copy()
        logging.info(f"SteamAPIClient initialized with country_code={country_code}, language={language}")

    def _make_request(self, endpoint: str, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
        """
        内部方法：发送HTTP GET请求到Steam API。
        Args:
            endpoint (str): API的端点 (e.g., 'appdetails').
            params (Dict[str, Any]): 请求参数。
        Returns:
            Optional[Dict[str, Any]]: 解析后的JSON响应数据，如果请求失败则返回None。
        """
        url = f"{self.BASE_URL}{endpoint}"
        full_params = {
            **params,
            "cc": self.country_code,
            "l": self.language
        }

        # 动态添加 Referer 头，模拟从商店主页或特定游戏页面跳转
        # 对于 appdetails 接口，模拟从该游戏的商店页面跳转更合理
        app_id_for_referer = params.get('appids', '')  # params可能包含单个或逗号分隔的appids
        # 如果是多个appids，我们取第一个来构建referer，或者直接用基URL
        if isinstance(app_id_for_referer, str) and ',' in app_id_for_referer:
            app_id_for_referer = app_id_for_referer.split(',')[0]

        if app_id_for_referer:
            self.headers["Referer"] = f"https://store.steampowered.com/app/{app_id_for_referer}/"
        else:
            self.headers["Referer"] = self.BASE_URL

        try:
            logging.debug(f"Requesting URL: {url} with params: {full_params} and headers: {self.headers}")
            response = requests.get(url, params=full_params, headers=self.headers, timeout=10)
            response.raise_for_status()

            data = response.json()
            return data
        except requests.exceptions.HTTPError as e:
            logging.error(
                f"HTTP error occurred for {url} with params {full_params}: {e.response.status_code} - {e.response.text}")
            return None
        except requests.exceptions.ConnectionError as e:
            logging.error(f"Connection error occurred for {url} with params {full_params}: {e}")
            return None
        except requests.exceptions.Timeout as e:
            logging.error(f"Request timed out for {url} with params {full_params}: {e}")
            return None
        except requests.exceptions.RequestException as e:
            logging.error(f"An unexpected request error occurred for {url} with params {full_params}: {e}")
            return None
        except ValueError as e:
            logging.error(f"Failed to decode JSON from response for {url} with params {full_params}: {e}")
            logging.debug(f"Raw response text: {response.text}")
            return None

    def get_game_details(self, app_id: int) -> Optional[Game]:
        """
        通过AppID获取单个游戏的详细信息。
        Args:
            app_id (int): Steam游戏的AppID。
        Returns:
            Optional[Game]: 如果成功获取并解析，返回Game对象，否则返回None。
        """
        logging.info(f"Fetching details for AppID: {app_id}")
        params = {"appids": app_id}
        data = self._make_request("appdetails", params)

        if not data or str(app_id) not in data or not data[str(app_id)].get("success", False):
            logging.warning(f"Could not retrieve successful data for AppID: {app_id}. Raw data: {data}")
            return None

        game_data = data[str(app_id)].get("data")
        if not game_data:
            logging.warning(f"Missing 'data' field for AppID: {app_id}. Raw data: {data}")
            return None

        return self._parse_game_data(app_id, game_data)

    # 移除了 get_multiple_game_details 方法

    def _parse_game_data(self, app_id: int, game_data: Dict[str, Any]) -> Optional[Game]:
        """
        内部方法：解析从appdetails API获取的原始游戏数据字典，创建Game对象。
        Args:
            app_id (int): 游戏的AppID。
            game_data (Dict[str, Any]): 原始游戏数据字典。
        Returns:
            Optional[Game]: 解析后的Game对象，如果数据不完整则返回None。
        """
        name = game_data.get("name")
        if not name:
            logging.warning(f"Missing name for AppID {app_id}, skipping parsing.")
            return None

        price = None
        initial_price = None
        discount_percent = None
        is_free = game_data.get("is_free", False)

        if "price_overview" in game_data:
            price_overview = game_data["price_overview"]
            price_cents = price_overview.get("final")
            initial_price_cents = price_overview.get("initial")
            discount_percent = price_overview.get("discount_percent")

            if price_cents is not None:
                price = price_cents / 100.0
            if initial_price_cents is not None:
                initial_price = initial_price_cents / 100.0
        elif is_free:
            price = 0.0

        recommendation_percent = None
        recommendation_total = None
        if "recommendations" in game_data:
            recommendations = game_data["recommendations"]
            recommendation_percent = recommendations.get("percent")
            recommendation_total = recommendations.get("total")

        release_date = None
        if "release_date" in game_data and game_data["release_date"].get("coming_soon") is False:
            release_date = game_data["release_date"].get("date")

        header_image_url = game_data.get("header_image")
        short_description = game_data.get("short_description")

        genres = []
        if "genres" in game_data:
            genres = [g.get("description") for g in game_data["genres"] if g.get("description")]

        return Game(
            app_id=app_id,
            name=name,
            price=price,
            initial_price=initial_price,
            discount_percent=discount_percent,
            is_free=is_free,
            recommendation_percent=recommendation_percent,
            recommendation_total=recommendation_total,
            release_date=release_date,
            header_image_url=header_image_url,
            short_description=short_description,
            genres=genres
        )
